package com.liqi.frame.comm.filter;

import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.liqi.frame.comm.Constants;
import com.liqi.frame.comm.dto.HttpResult;
import com.liqi.frame.comm.enums.ResultEnum;
import com.liqi.frame.comm.po.User;
import com.liqi.frame.comm.properties.MockUserProperties;
import com.liqi.frame.comm.token.TokenUtil;
import com.liqi.frame.comm.token.UserToken;
import com.liqi.frame.comm.util.AjaxUtil;
import com.liqi.frame.comm.util.ShiroUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 
 * 判断登录
 */
@Slf4j
public class LoginFilter extends AccessControlFilter {
//	private static final Log log = LogFactory.get();

	private String unauthorizedUrl;
	public String getUnauthorizedUrl() {
		return unauthorizedUrl;
	}

	public void setUnauthorizedUrl(String unauthorizedUrl) {
		this.unauthorizedUrl = unauthorizedUrl;
	}

	private MockUserProperties mockUserProperties;
	public LoginFilter(MockUserProperties mockUserProperties){
		this.mockUserProperties = mockUserProperties;
	}

	/**
	 * 表示是否允许访问 ，如果允许访问返回true，否则false
	 * @param request
	 * @param response
	 * @param mappedValue
	 * @return
	 * @throws Exception
	 */
	@Override
	protected boolean isAccessAllowed(ServletRequest request,
                                      ServletResponse response, Object mappedValue) throws Exception {
		User token = TokenUtil.getToken();

		if (null == token && mockUserProperties!=null && !Objects.equals("off", mockUserProperties.getEnable())) {
			String username = mockUserProperties.getUsername();
			String pswd = mockUserProperties.getPswd();
			User user = new User();
			user.setUsername(username);
			user.setPswd(pswd);
			UserToken userToken = new UserToken(user.getUsername(), user.getPswd());
			ShiroUtil.getSubject().login(userToken);
			token = TokenUtil.getToken();
		}

		if(null != token || isLoginRequest(request, response)){// && isEnabled()
            return Boolean.TRUE;
        }
		if (AjaxUtil.isAjax(request)) {// ajax请求
			String url = WebUtils.getPathWithinApplication(WebUtils.toHttp(request));
			if (url.equalsIgnoreCase(Constants.LOGIN_AJAX_URL)) {
				// ajax的登录请求
				return Boolean.TRUE;
			}
			Map<String, String> resultMap = new HashMap<String, String>();
			log.debug( "当前用户没有登录，并且是Ajax请求！");
			resultMap.put("httpStatus", "300");
			resultMap.put("message", "当前用户没有登录！");//当前用户没有登录！
			AjaxUtil.out(response, resultMap);
		}
		return Boolean.FALSE ;
            
	}

	/**
	 * 如果返回 true 表示需要继续处理；如果返回 false 表示该拦截器实例已经处理了，将直接返回即可。
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response)
			throws Exception {

		Subject subject = getSubject(request, response);
		if (subject.getPrincipal() == null) {
//			if (!AjaxUtil.isAjax(request)) {
//				HttpResult result = new HttpResult(false, "您尚未登录或登录时间过长,请重新登录!");
//				AjaxUtil.out(response, result);
//			} else {
				//将当前请求保存起来并重定向到登录页面
				saveRequestAndRedirectToLogin(request, response);
//			}
		} else {
			if (!AjaxUtil.isAjax(request)) {
				HttpResult result = new HttpResult(ResultEnum.FAILURE, "您没有足够的权限执行该操作!");
				AjaxUtil.out(response, result);
			} else {

				String unauthorizedUrl = getUnauthorizedUrl();
				if (StrUtil.isNotEmpty(unauthorizedUrl)) {
					WebUtils.issueRedirect(request, response, unauthorizedUrl);
				} else {
					WebUtils.toHttp(response).sendError(404);
				}
			}
		}
		return Boolean.FALSE ;
	}
	

}
